#include <math.h>
#include "Miro.h"
#include "Scene.h"
#include "Camera.h"
#include "Image.h"
#include "Console.h"

#include "PointLight.h"
#include "Sphere.h"
#include "TriangleMesh.h"
#include "Triangle.h"
#include "Lambert.h"
#include "MiroWindow.h"

#include "assignment1.h"

Vector3 lerp(Vector3 a, Vector3 b, float t)
{
	return (1-t)*a+t*b;
}

void
makeSpiralScene()
{
    g_camera = new Camera;
    g_scene = new Scene;
    g_image = new Image;

    g_image->resize(512, 512);
    
    // set up the camera
    g_camera->setBGColor(Vector3(1.0f, 1.0f, 1.0f));
    g_camera->setEye(Vector3(-5, 2, 3));
    g_camera->setLookAt(Vector3(0, 0, 0));
    g_camera->setUp(Vector3(0, 1, 0));
    g_camera->setFOV(45);

    // create and place a point light source
    PointLight * light = new PointLight;
    light->setPosition(Vector3(-3, 15, 3));
    light->setColor(Vector3(1, 1, 1));
    light->setWattage(1000);
    g_scene->addLight(light);

    // create a spiral of spheres
    //Material* mat = new Lambert(Vector3(1.0f, 0.0f, 0.0f));
    const int maxI = 200;
    const float a = 0.15f;
    for (int i = 1; i < maxI; ++i)
    {
        float t = i/float(maxI);
        float theta = 4*PI*t;
        float r = a*theta;
        float x = r*cos(theta);
        float y = r*sin(theta);
        float z = 2*(2*PI*a - r);
        Sphere * sphere = new Sphere;
        sphere->setCenter(Vector3(x,y,z));
        sphere->setRadius(r/10);
        Material *mat = new Lambert(lerp(Vector3(1,0,1), Vector3(1,1,0), t));
        sphere->setMaterial(mat);
        g_scene->addObject(sphere);
    }
    
    // let objects do pre-calculations if needed
    g_scene->preCalc();
}

float cx(float A, float B, float t)
{
	return A*cos(B*t);
}

float cy(float A, float B, float t)
{
	return A*sin(B*t);
}

void
makeSpirographScene()
{
    g_camera = new Camera;
    g_scene = new Scene;
    g_image = new Image;

    g_image->resize(512, 512);
    
    // set up the camera
    g_camera->setBGColor(Vector3(1.0f, 1.0f, 1.0f));
    g_camera->setEye(Vector3(-5, 2, 3));
    g_camera->setLookAt(Vector3(0, 0, 0));
    g_camera->setUp(Vector3(0, 1, 0));
    g_camera->setFOV(45);

    // create and place a point light source
    PointLight * light = new PointLight;
    light->setPosition(Vector3(-3, 15, 3));
    light->setColor(Vector3(1, 1, 1));
    light->setWattage(1000);
    g_scene->addLight(light);

    // create a spiral of spheres
    //Material* mat = new Lambert(Vector3(1.0f, 0.0f, 0.0f));
    const int maxI = 1200;
    const float a = 0.15f;
    
    
    float AX = 1.15f;
	float AY = 1.5f;
	float AZ = 0.15f;
	float BX = 0.105f;
	float BY = 15.0f;
	float BZ = 150.0f;
    /*float AX = 3.20f;
    float AY = 4.40f;
    float AZ = 1.20f;
    float BX = 2.10f;
    float BY = 0100.00f;
    float BZ = 50.10f;*/
    
    for (int i = 1; i < maxI; ++i)
    {
        float t = i/float(maxI);
        float theta = 4*PI*t;
        float r = a*theta;
        float x = cx(AX,AY,t)+cy(AZ,BZ,t);//r*cos(theta);
        float y = cy(AX,AX,t)+cx(AY,BY,t);//r*sin(theta);
        float z = cx(AZ,BZ,t)+cy(AY,BY,t);//2*(2*PI*a - r);
        Material *mat = new Lambert(lerp(Vector3(1,0,0), Vector3(0,1,1), t));
        Sphere * sphere = new Sphere;
        sphere->setCenter(Vector3(x,y,z));
        sphere->setRadius(.1);//r/10);
        sphere->setMaterial(mat);
        g_scene->addObject(sphere);
    }
    
    for (int i = maxI; i < 2*maxI; ++i)
    {
        float t = i/float(maxI);
        float theta = 4*PI*t;
        float r = a*theta;
        float x = cx(AX,AY,t)+cy(AZ,BZ,t);//r*cos(theta);
        float y = cy(AX,AX,t)+cx(AY,BY,t);//r*sin(theta);
        float z = cx(AZ,BZ,t)+cy(AY,BY,t);//2*(2*PI*a - r);
        Material *mat = new Lambert(lerp(Vector3(0,1,1), Vector3(1,1,0), t-1));
        Sphere * sphere = new Sphere;
        sphere->setCenter(Vector3(x,y,z));
        sphere->setRadius(.1);//r/10);
        sphere->setMaterial(mat);
        g_scene->addObject(sphere);
    }
    
    for (int i = 2*maxI; i < 3*maxI; ++i)
    {
        float t = i/float(maxI);
        float theta = 4*PI*t;
        float r = a*theta;
        float x = cx(AX,AY,t)+cy(AZ,BZ,t);//r*cos(theta);
        float y = cy(AX,AX,t)+cx(AY,BY,t);//r*sin(theta);
        float z = cx(AZ,BZ,t)+cy(AY,BY,t);//2*(2*PI*a - r);
        Material *mat = new Lambert(lerp(Vector3(1,1,0), Vector3(1,0,1), t-2));
        Sphere * sphere = new Sphere;
        sphere->setCenter(Vector3(x,y,z));
        sphere->setRadius(.1);//r/10);
        sphere->setMaterial(mat);
        g_scene->addObject(sphere);
    }
    
    // let objects do pre-calculations if needed
    g_scene->preCalc();
}



int
main(int argc, char*argv[])
{
    // create a scene
    //makeSpiralScene();
    //makeSpirographScene();
    makeBunnyScene();
    //makeBilinearPatchScene();

    MiroWindow miro(&argc, argv);
    miro.mainLoop();

    return 0; // never executed
}

